PKI with step-ca and nixOS ACME
Using ACME to obtain certificates very often involves the following two things:
- Let's Encrypt
- Having a domain with some sort of reverse proxy running
In the context of intranet infrastructure/corporate/homelab: But what if you want to use the built-in ACME module of nixOS instead and especially in-order to have auto-renewal/rolling certificates for a service that is not even publicly or even internally only partially exposed? And on top of that on a made up FQDN. (Obviously this is not going to be trust by a global root CA)
Well it is kind of easy, you need the following:
- ACME capable CA which handles challenges and issuing certs/signing material
- nixOS ACME module (which is already there out of the box)
- A tiny reverse proxy which can serve certain files from disk (the challenge material)
That is almost it. Now it is "only" a matter of configuration.
In my case I choose step-ca as CA and caddy as reverse-proxy/dumb-challenge-response server.
Now you need to tweak the ACME module to use whatever DNS you point to your challenge server (CA, step-ca). Then have the ACME module and webserver have a shared directory to write and read from (I ran into a bit of issues here because of permission issues).
E.g., /var/lib/acme/.challenges.
Configure step-ca so that it has an ACME provisioner and set the list of allowed challenges to the ones you want to expose, e.g., like me, configure EVERY ACME challenge except http-01 which is the only relevant here and scratch your head why nothing works.
The CA/ACME provider need to be able to reach the challenge-response server, otherwise it cannot confirm the challenge. And the ACME module/nixOS systemd service (mostly a wrapper around a cool golang CLI tool) needs to obviously also be able to reach the CA/ACME provider.
This already does most of what we want, but to make sure the service we are requesting new certs for knows it has to "reload" we add the service (assuming you have it running as systemd service) to the list of reloadServices in the ACME module for the respective cert/fqdn entry.
Is this a recommended approach? Not necessarily, but it is rather easy and convenient to ensure renewed certificates without building any elaborate certificate renewal process yourself and simply tapping into existing techniques albeit "miss"-using them a bit. bit.
If this blog post was too light on details for you, hit me up and I can share more details with you. Via @tallyho-dulcet:matrix.org (Might take a while to reply) or LinkedIn